package com.luoyi.util.mpaas.common;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * word模板参数解析
 *
 * @author xt
 */
@Slf4j
public class WordParamAnalysis {

    /**
     * 正则表达式模式，用于匹配{{}}
     */
    final private static Pattern PATTERN = Pattern.compile("\\{\\{[^}]+\\}\\}");

    /**
     * 匹配 {{&fe:*
     */
    final public static Pattern PATTERN2 = Pattern.compile("^\\{\\{&fe:[a-zA-Z0-9_]+");

    /**
     * 匹配 t.*
     */
    final public static Pattern PATTERN3 = Pattern.compile("^t\\.[a-zA-Z0-9_]+");


    /**
     * 匹配 t.*}}
     */
    final public static Pattern PATTERN4 = Pattern.compile("^t\\.[a-zA-Z0-9_]+\\}\\}");

    /**
     * 执行转换操作
     *
     * @param inFile 输入文件
     */
    public JSONObject execute(File inFile) {
        FileInputStream fis = null;
        XWPFDocument document = null;
        JSONObject jsonObject = new JSONObject();
        try {
            // 检查文件是否存在、是否是文件、是否是 .docx 文件
            if (!inFile.exists() || !inFile.isFile() || !inFile.getName().toLowerCase().endsWith(".docx")) {
                log.error("提供的文件不是有效的 .docx 文件: {}", inFile.getAbsolutePath());
                throw new RuntimeException("提供的文件不是有效的 .docx 文件：" + inFile.getAbsolutePath());
            }
            fis = new FileInputStream(inFile);
            document = new XWPFDocument(fis);
            // 段落文本处理
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                paragraphText(paragraph, jsonObject);
            }
            // 表格处理
            for (int i = 0; i < document.getTables().size(); i++) {
                tableText(document.getTables().get(i), jsonObject);
            }
            // 页眉处理
            for (XWPFHeader header : document.getHeaderList()) {
                // 获取页眉中的所有形状
                for (XWPFParagraph paragraph : header.getParagraphs()) {
                    if (paragraph != null) {
                        paragraphText(paragraph, jsonObject);
                    }
                }
            }
        } catch (IOException e) {
            log.error("读取文件时发生错误:{}", inFile.getAbsolutePath(), e);
            throw new RuntimeException("读取文件时发生错误:" + e.getMessage());
        } finally {
            try {
                if (document != null) {
                    document.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                log.error("关闭文件流时发生错误", e);
            }
        }
        return jsonObject;
    }

    /**
     * 处理表格文本
     *
     * @param xwpfTable 表格
     * @param jsonObject JSON对象
     */
    private void tableText(XWPFTable xwpfTable, JSONObject jsonObject) {
        for (int i = 0; i < xwpfTable.getRows().size(); i++) {
            int cellSize = xwpfTable.getRow(i).getTableCells().size();
            boolean isTableParam = false;
            String tableName = null;
            for (int j = 0; j < cellSize; j++) {
                StringBuilder cellText = new StringBuilder();
                List<XWPFParagraph> paragraphs = xwpfTable.getRow(i).getCell(j).getParagraphs();
                for (XWPFParagraph paragraph : paragraphs) {
                    cellText.append(paragraph.getText());
                }
                String text = cellText.toString();
                if (j == 0) {
                    // 第一列  匹配 {{&fe:* t.*
                    String[] split = text.split(" ");
                    if (split.length == 2) {
                        Matcher matcher = PATTERN2.matcher(split[0]);
                        boolean matches = matcher.matches();
                        Matcher matcher2 = PATTERN3.matcher(split[1]);
                        boolean matches2 = matcher2.matches();
                        isTableParam = matches && matches2;
                        if (isTableParam) {
                            tableName = split[0].split("\\{\\{&fe:")[1];
                            String field = split[1].split("\\.")[1];
                            setCellTableParam(jsonObject, tableName, field);
                        }
                    }
                } else if (j == cellSize - 1 && isTableParam) {
                    // 最后一列  匹配 t.*}}
                    Matcher matcher = PATTERN4.matcher(text);
                    if (matcher.matches()) {
                        String textItem = text.split("\\.")[1];
                        String field = textItem.substring(0, textItem.length() - 2);
                        setCellTableParam(jsonObject, tableName, field);
                    }
                } else {
                    if (isTableParam) {
                        // 中间列 匹配 t.*
                        Matcher matcher = PATTERN3.matcher(text);
                        if (matcher.matches()) {
                            setCellTableParam(jsonObject, tableName, text.split("\\.")[1]);
                        }
                    }
                }
                if (!isTableParam) {
                    // 不是表格参数时，每个cell按段落处理
                    paragraphs.forEach(paragraph -> paragraphText(paragraph, jsonObject));
                }
            }
        }
    }

    private void setCellTableParam(JSONObject jsonObject, String tableName, String field) {
        JSONArray jsonArray = jsonObject.getJSONArray(tableName);
        if (jsonArray == null) {
            jsonArray = new JSONArray();
            jsonObject.put(tableName, jsonArray);
        }
        JSONObject jsonItem;
        if (jsonArray.isEmpty()) {
            jsonItem = new JSONObject();
            jsonArray.add(jsonItem);
        } else {
            jsonItem = jsonArray.getJSONObject(0);
        }
        jsonItem.put(field, StrUtil.EMPTY);
    }

    /**
     * 解析段落文本
     *
     * @param paragraph 段落
     * @param jsonObject json对象
     */
    private void paragraphText(XWPFParagraph paragraph, JSONObject jsonObject) {
        List<XWPFRun> runs = paragraph.getRuns();
        if (runs == null || runs.isEmpty()) {
            return;
        }
        StringBuilder paragraphText = new StringBuilder();
        for (XWPFRun run : runs) {
            paragraphText.append(run.getText(0));
        }
        String text = paragraphText.toString();
        Matcher matcher = PATTERN.matcher(text);
        while (matcher.find()) {
            String match = matcher.group();
            String substring = match.substring(2, match.length() - 2);
            jsonObject.put(substring, StrUtil.EMPTY);
        }
    }





    public static void main(String[] args) {
        File inFile = new File("D:\\fileTest\\3.docx");
        WordParamAnalysis wordParamTagRed = new WordParamAnalysis();
        JSONObject execute = wordParamTagRed.execute(inFile);
        System.out.println(execute.toJSONString());
    }

}
